package com.wman;

import java.util.concurrent.BlockingDeque;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 多线程创建
 * Synchronized 资源访问问题
 * Synchronized 数据同步问题
 * 默认的Synchronized是对象
 * 死锁：不同线程相互拿着别人需要的锁
 *
 * 数据库方面的概念
 * 乐观锁:先不加锁，数据被改了再加锁
 * 悲观锁：常规的加锁方式
 *
 * static如何加锁：默认的Synchronized是类
 * volatile：小型的Synchronized   原子性和同步性，double和long的某些操作不一定是原子操作，加上了就能保证，
 *  只针对基本类型和对象赋值才能保证原子操作，比如a++就不能保证原子
 * Atomic* 能保证a++是原子操作
 */
public class Main {
    private AtomicInteger a;

    public static void main(String[] args) {
//        thread();
//        runnable();
//        threadFactory();
//        executor();
//        callable();
//        runSynchronized1Demo();
//        runSynchronized2Demo();
        runSynchronized3Demo();
    }

    private static void thread() {
        Thread thread = new Thread() {
            @Override
            public void run() {
                super.run();
                System.out.println("Thread Started!");
            }
        };

        thread.start();
    }

    private static void runnable() {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("Thread with Runnable Started!");
            }
        };

        Thread thread = new Thread(runnable) {
            @Override
            public void run() {
                //这里的super是执行runnable的东西
                super.run();
                System.out.println("Thread Started!");
            }
        };
        thread.start();
    }

    /**
     * 作用：统一规则的初始化
     */
    public static void threadFactory() {
        ThreadFactory factory = new ThreadFactory() {
            AtomicInteger count = new AtomicInteger(0);

            @Override
            public Thread newThread(Runnable runnable) {
                return new Thread("Thread-" + count.incrementAndGet());
            }
        };

        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("Thread with Runnable Started!");
                System.out.println(Thread.currentThread().getName() + " started!");
            }
        };

        Thread thread = factory.newThread(runnable);
        thread.start();
        Thread thread1 = factory.newThread(runnable);
        thread1.start();
    }

    public static void executor() {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("Thread with Runnable Started!");
            }
        };

        ExecutorService executor = Executors.newCachedThreadPool();
        executor.execute(runnable);
        executor.execute(runnable);
        executor.execute(runnable);
        executor.execute(runnable);
        executor.shutdown();//保守型的结束，都执行完毕才结束，不允许新任务
//        executor.shutdownNow();//立即结束

        // 自定义创建线程池
        BlockingDeque queue = new LinkedBlockingDeque<>(1000);
        ExecutorService executorPool = new ThreadPoolExecutor(5, 100, 5L, TimeUnit.SECONDS, queue);
        executorPool.shutdown();

//        ExecutorService fixexExecutor = Executors.newFixedThreadPool(20);
//        for (int i = 0; i < 20; i++) {
//            fixexExecutor.execute(new Runnable() {
//                @Override
//                public void run() {
//
//                }
//            });
//        }
//        fixexExecutor.shutdownNow();
    }

    /**
     * 有返回值的Runnable
     * 可用度很少
     */
    private static void callable() {
        Callable<String> callable = new Callable<String>() {
            @Override
            public String call() throws Exception {
                try {
                    Thread.sleep(2500);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return "Done!";
            }
        };

        ExecutorService executorService = Executors.newCachedThreadPool();
        Future<String> future = executorService.submit(callable);
        while (true) {
            if (future.isDone()) {
                try {
                    //get阻塞获取
                    future.isDone();
                    String resule = future.get();
                    System.out.println("resule:" + resule);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void runSynchronized1Demo() {
        new Synchronized1Demo().runTest();
    }

    public static void runSynchronized2Demo() {
        new Synchronized2Demo().runTest();
    }

    public static void runSynchronized3Demo() {
        new Synchronized3Demo().runTest();
    }
}
